//
//  UserManager.m
//  高仿暴走斗图
//
//  Created by huangsongyao on 16/3/4.
//  Copyright © 2016年 huangsongyao. All rights reserved.
//

#import "UserManager.h"
#import "NSObject+Runtime.h"
#import "NSObject+Json.h"

static UserManager *userManager;

#define LOCALCONFIGURATION_KEY              @"com.HSY.locationConfig"

static NSString *const kUserId              = @"com.HSY.kUserId";
static NSString *const kStatusType          = @"com.HSY.kStatusType";
static NSString *const kIcon                = @"com.HSY.kIcon";
static NSString *const kUserGender          = @"com.HSY.kUserGender";
static NSString *const kDeviceToken         = @"com.HSY.kDeviceToken";
static NSString *const kVersion             = @"com.HSY.kVersion";
static NSString *const kJSONModel           = @"com.HSY.kJSONModel";


@implementation UserManager

@synthesize userId                          = _userId;
@synthesize userStatusType                  = _userStatusType;
@synthesize icon                            = _icon;
@synthesize userGender                      = _userGender;
@synthesize deviceToken                     = _deviceToken;
@synthesize version                         = _version;
@synthesize jsonModel                       = _jsonModel;

+ (instancetype)shareInstance {
    
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        userManager = [[UserManager alloc] init];
    });
    return userManager;
}

- (instancetype)init {
    
    if (self = [super init]) {
        NSLog(@"UserManager");
        [UserManager initWithLocalConfiguration];
    }
    return self;
}


#pragma mark - User Location Configuration

+ (void)saveLocalConfiguration:(NSString *)config {
 
    NSDictionary *info = [[NSUserDefaults standardUserDefaults] dictionaryForKey:LOCALCONFIGURATION_KEY];
    NSMutableDictionary *newInfo = [NSMutableDictionary dictionaryWithDictionary:info];
    
    id value = nil;
    if ([config isEqualToString:kUserId]) {
        
        value = [[UserManager shareInstance] userId];
        
    } else if ([config isEqualToString:kStatusType]) {
        
        value = [NSNumber numberWithInteger:[[UserManager shareInstance] userStatusType]];
        
    } else if ([config isEqualToString:kIcon]) {
        
        value = [[UserManager shareInstance] icon];
        
    } else if ([config isEqualToString:kUserGender]) {
        
        value = [NSNumber numberWithInteger:[[UserManager shareInstance] userGender]];
        
    } else if ([config isEqualToString:kDeviceToken]) {
        
        value = [[UserManager shareInstance] deviceToken];
        
    } else if ([config isEqualToString:kVersion]) {
        
        value = [[UserManager shareInstance] version];
        
    }
    
    if (value) {
        //添加对象的互斥锁，保证临界区内的代码线程安全
        @synchronized (newInfo) {
            
            [newInfo setObject:value forKey:config];
            [[NSUserDefaults standardUserDefaults] setObject:newInfo forKey:LOCALCONFIGURATION_KEY];
            [[NSUserDefaults standardUserDefaults] synchronize];
        }
    }
}

+ (RACSignal *)initWithLocalConfiguration {
    
    NSUserDefaults *userDefault = [NSUserDefaults standardUserDefaults];
    NSDictionary *info = [userDefault objectForKey:LOCALCONFIGURATION_KEY];
    if (!info) {
        
        //若本地数据为空的时候先存入默认的值
        info = @{
                 kUserId         : @"",
                 kIcon           : @"",
                 kDeviceToken    : @"",
                 kVersion        : @"",
                 kStatusType     : @(kUserStatusTypeNone),
                 kUserGender     : @(kUserGenderTypeNone),
                 kJSONModel      : [[HSYJSONModel news] toJSONString],
                 };
        
        [userDefault setObject:info forKey:LOCALCONFIGURATION_KEY];
        [userDefault synchronize];
    }
    
    return [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
       //添加对象的互斥锁，保证临界区内的代码线程安全
        @synchronized (userDefault) {
            [[[userDefault rac_channelTerminalForKey:LOCALCONFIGURATION_KEY] deliverOn:[RACScheduler mainThreadScheduler]] subscribeNext:^(id x) {
                
                NSDictionary *info = [NSObject resolveToJsonObject:x];
                [UserManager shareInstance].userId              = info[kUserId];
                [UserManager shareInstance].icon                = info[kIcon];
                [UserManager shareInstance].deviceToken         = info[kDeviceToken];
                [UserManager shareInstance].version             = info[kVersion];
                [UserManager shareInstance].userStatusType      = [info[kStatusType] integerValue];
                [UserManager shareInstance].userGender          = [info[kUserGender] integerValue];
                [UserManager shareInstance].jsonModel           = info[kJSONModel];
                
                [subscriber sendNext:info];
                [subscriber sendCompleted];
            }];
        }
        return nil;
    }];
}


#pragma mark Getting && Saving

//*********************************************NSString***************************************************//

- (NSString *)getUserID {
    
    return [UserManager shareInstance].userId;
}

- (void)saveUserID:(NSString *)userID {
    
    [UserManager shareInstance].userId = userID;
    [UserManager saveLocalConfiguration:kUserId];
}

- (NSString *)getIcon {
    
    return [UserManager shareInstance].icon;
}

- (void)saveIcon:(NSString *)icon {
    
    [UserManager shareInstance].icon = icon;
    [UserManager saveLocalConfiguration:kIcon];
}


- (NSString *)getDeviceToken {
    
    return [UserManager shareInstance].deviceToken;
}

- (void)saveDeviceToken:(NSString *)deviceToken {
    
    [UserManager shareInstance].deviceToken = deviceToken;
    [UserManager saveLocalConfiguration:kDeviceToken];
}


//*********************************************NSNumber***************************************************//

- (kUserStatusType)getUserStatus {
    
    NSInteger userStatus = [UserManager shareInstance].userStatusType;
    return (kUserStatusType)userStatus;
}

- (void)saveUserStatusType:(kUserStatusType)userStatusType {
    
    [UserManager shareInstance].userStatusType = userStatusType;
    [UserManager saveLocalConfiguration:kStatusType];
}


- (kUserGenderType)getUserGender {
    
    NSInteger userGender = [UserManager shareInstance].userGender;
    return (kUserGenderType)userGender;
}

- (void)saveUserGender:(kUserGenderType)userGender {
    
    [UserManager shareInstance].userGender = userGender;
    [UserManager saveLocalConfiguration:kUserGender];
}

//*********************************************JSONModel***************************************************//

- (HSYJSONModel *)getJSONModel {
    
    if ([[UserManager shareInstance].jsonModel isKindOfClass:[HSYJSONModel class]]) {
        
        //使用try语句做一个保险
        @try {
            //执行的代码，其中可能有异常。一旦发现异常，则立即跳到catch执行。否则不会执行catch里面的内容
            return [UserManager shareInstance].jsonModel;
            
        } @catch (NSException *exception) {
            //除非try里面执行代码发生了异常，否则这里的代码不会执行
            NSLog(@"获取JSONModel缓存发生异常");
        } @finally {
            //不管什么情况都会执行，包括try catch 里面用了return ,可以理解为只要执行了try或者catch，就一定会执行 finally
        }
        
    } else {
        
        HSYJSONModel *jsonModel = [NSObject resultObjectToJSONModelWithClasses:[NSObject getObjectClassForInfo:[UserManager shareInstance].jsonModel] json:[UserManager shareInstance].jsonModel];
        
        return jsonModel;
    }
}

- (void)saveJSONModel:(HSYJSONModel *)jsonModel {
    
    [UserManager shareInstance].jsonModel = jsonModel;
    [UserManager saveLocalConfiguration:kJSONModel];
}


@end

